import logging
import os
import socketserver
from http.server import BaseHTTPRequestHandler, HTTPServer

import requests

from wechat.webot.entity import *

logging.basicConfig(level=logging.INFO)


def _get_self_info(base_url) -> SelfInfo | None:
    try:
        response = requests.post(base_url, json={'type': 3})
        self_info = SelfInfo(response.json().get('data'))
        logging.info(f"获取个人信息成功 [{self_info.nick_name}]...")
        return self_info
    except Exception as e:
        logging.warning(f"获取个人信息失败 {e.args}")
        return None


def _get_pull_info(base_url, pull_type: int) -> list[WxEntity]:
    """
    获取好友或者群信息
    :param pull_type: 1:好友 2:群
    """
    try:
        response = requests.post(base_url, json={'type': 5, 'pull_type': pull_type})
        data_list = response.json().get('data').get('list')
        return [WxEntity(item) for item in data_list]
    except Exception as e:
        logging.warning(f"获取信息失败 {e.args}")
        return []


def _get_chat_room_member(base_url, chat_room_wx_id) -> list[WxEntity]:
    """
    获取群成员信息
    :param chat_room_wx_id: 群id
    """
    try:
        response = requests.post(base_url, json={'type': 6, 'chat_room_id': chat_room_wx_id})
        data_list = response.json().get('data').get('list')
        return [WxEntity(item) for item in data_list]
    except Exception as e:
        logging.warning(f"获取信息失败 {e.args}")
        return []


def get_wx_context(base_url):
    return WxContext(_get_self_info(base_url), _get_pull_info(base_url, 1), _get_pull_info(base_url, 2))


def send_msg(base_url, wx_id, msg):
    """
    向指定wx_id,发送文本消息
    """
    try:
        response = requests.post(base_url, json={'type': 7, 'wx_id': wx_id, 'msg': msg})
        data = response.json()
        if data.get('errno') != 0:
            logging.warning(f"发送消息失败: {data.get('errmsg')}")
    except Exception as e:
        logging.warning(f"发送消息失败: {e.args}")


def send_img(base_url, wx_id, path):
    """
        向指定wx_id,发送图片消息
    """
    try:
        response = requests.post(base_url, json={'type': 8, 'wx_id': wx_id, 'path': path})
        data = response.json()
        if data.get('errno') != 0:
            logging.warning(f"发送消息失败: {data.get('errmsg')}")
    except Exception as e:
        logging.warning(f"发送消息失败: {e.args}")


def send_file(base_url, wx_id, path):
    """
        向指定wx_id,发送文件或者视频
    """
    try:
        response = requests.post(base_url, json={'type': 9, 'wx_id': wx_id, 'path': path})
        data = response.json()
        if data.get('errno') != 0:
            logging.warning(f"发送消息失败: {data.get('errmsg')}")
    except Exception as e:
        logging.warning(f"发送消息失败: {e.args}")


# 定义一个处理 HTTP 监听消息
class _RequestHandler(BaseHTTPRequestHandler):

    def __init__(self, request: bytes, client_address: tuple[str, int], server: socketserver.BaseServer,
                 handleMessageFun):
        self.handleMessageFun = handleMessageFun
        super().__init__(request, client_address, server)

    def do_POST(self):
        # 设置响应状态码和响应头
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        # 获取 POST 数据的长度
        content_length = int(self.headers['Content-Length'])
        # 解析 POST 数据
        post_data = self.rfile.read(content_length).decode('utf-8')
        wx_message = WxMessage(json.loads(post_data))
        try:
            self.handleMessageFun(wx_message)
        finally:
            # 构造响应内容
            response_content = "200"
            # 发送响应内容
            self.wfile.write(response_content.encode('utf-8'))

    def do_GET(self):
        # 获取请求的路径
        request_path = self.path
        # 检查路径是否以 /download/ 开头
        if request_path.startswith('/download/'):
            # 获取文件名
            file_name = request_path[len('/download/'):]
            # 设置文件路径
            file_path = os.path.join(os.getcwd() + r'/temp/', file_name)
            # 检查文件是否存在
            if os.path.exists(file_path) and os.path.isfile(file_path):
                # 读取文件内容
                with open(file_path, 'rb') as file:
                    file_content = file.read()
                # 发送响应状态码
                self.send_response(200)
                # 设置响应头
                self.send_header('Content-Type', 'application/octet-stream')
                self.send_header('Content-Disposition', f'attachment; filename="{file_name}"')
                self.end_headers()
                # 发送文件内容
                self.wfile.write(file_content)
            else:
                # 文件不存在，发送404响应
                self.send_response(404)
                self.send_header('Content-Type', 'text/html')
                self.end_headers()
                self.wfile.write(b"File not found.")
        else:
            # 对于其他路径的请求，发送404响应
            self.send_response(404)
            self.send_header('Content-Type', 'text/html')
            self.end_headers()
            self.wfile.write(b"Path not found.")


# 微信消息监听器
class WeMessageListener(HTTPServer):

    def __init__(self, handleMessageFun, host='127.0.0.1', port=9000):
        """
        :param handleMessageFun: 处理消息的函数 会传入一个WxMessage对象 没有返回值
        """
        self.handleMessageFun = handleMessageFun
        super().__init__((host, port), _RequestHandler)
        # 启动服务器
        logging.info(f'WeMessageListener started on {host}:{port}')
        self.serve_forever()

    def finish_request(self, request, client_address) -> None:
        self.RequestHandlerClass(request, client_address, self, self.handleMessageFun)


if __name__ == '__main__':
    base_url = "http://127.0.0.1:8989/api"
    # print("个人信息", _get_self_info(base_url))
    # print("好友列表", _get_pull_info(base_url, 1))
    # print("群信息", _get_pull_info(base_url, 2))
    # print("群成员", _get_chat_room_member(base_url, "48860286023@chatroom"))
    print(get_wx_context(base_url))
